package com.example.teacherservice.controller;

import com.example.teacherservice.dto.*;
import com.example.teacherservice.entity.*;
import com.example.teacherservice.entity.Class;
import com.example.teacherservice.repository.*;
import com.example.teacherservice.service.ClassService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@RestController
@Transactional
@RequestMapping("/api/spoc/cla")
public class ClassController {
    private final ClassService classService;
    private final CouClassRepository couClassRepository;
    private final ClassRepository classRepository;
    private final CourseRepository courseRepository;
    private final StudentRepository studentRepository;
    private final StuClassRepository stuClassRepository;

    public ClassController(ClassService classService,CouClassRepository couClassRepository,ClassRepository classRepository,CourseRepository courseRepository,StudentRepository studentRepository,StuClassRepository stuClassRepository) {
        this.classService = classService;
        this.couClassRepository = couClassRepository;
        this.classRepository = classRepository;
        this.courseRepository = courseRepository;
        this.studentRepository = studentRepository;
        this.stuClassRepository = stuClassRepository;
    }

    @GetMapping("/full-detail/{id}")
    public ResponseEntity<?> getClassDetailEnhanced(@PathVariable Long id) {
        try {
            return classService.getClassFullDetail(id);
        } catch (Exception e) {
            log.error("获取班级详情失败", e);
            return errorResponse("获取班级详情失败", e);
        }
    }

    @GetMapping("/listAll")
    public ResponseEntity<?> listAllClasses() {
        try {
            List<Class> classes = classService.findAllClasses();
            List<ClassDTO> dtos = classes.stream()
                    .map(this::convertToClassDTO)
                    .collect(Collectors.toList());
            return ResponseEntity.ok(dtos);
        } catch (Exception e) {
            log.error("获取班级列表失败", e);
            return errorResponse("获取班级列表失败", e);
        }
    }

    @GetMapping("/listAll/{page}/{limit}")
    public ResponseEntity<?> listAllClasses(
            @PathVariable int page,
            @PathVariable int limit) {
        try {
            Page<Class> classes = classService.findAllClasses(page, limit);
            Page<ClassDTO> dtos = classes.map(this::convertToClassDTO);
            return ResponseEntity.ok(dtos);
        } catch (Exception e) {
            log.error("获取分页班级列表失败", e);
            return errorResponse("获取分页班级列表失败", e);
        }
    }

    @PostMapping("/batchCreate")
    public ResponseEntity<?> batchCreateClasses(@RequestBody List<Class> classes) {
        try {
            List<Class> createdClasses = classService.batchCreateClasses(classes);
            List<ClassDTO> dtos = createdClasses.stream()
                    .map(this::convertToClassDTO)
                    .collect(Collectors.toList());
            return ResponseEntity.ok(dtos);
        } catch (Exception e) {
            log.error("批量创建班级失败", e);
            return errorResponse("批量创建班级失败", e);
        }
    }

    @GetMapping("/{id}")
    public ResponseEntity<?> getClassDetail(@PathVariable Long id) {
        try {
            Class cls = classService.getClassById(id);
            return ResponseEntity.ok(convertToClassDTO(cls));
        } catch (Exception e) {
            log.error("获取班级详情失败", e);
            return errorResponse("获取班级详情失败", e);
        }
    }

    @PutMapping("/{id}")
    public ResponseEntity<?> updateClass(
            @PathVariable Long id,
            @RequestBody Class classUpdate) {
        try {
            Class updatedClass = classService.updateClass(id, classUpdate);
            return ResponseEntity.ok(convertToClassDTO(updatedClass));
        } catch (Exception e) {
            log.error("更新班级失败", e);
            return errorResponse("更新班级失败", e);
        }
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<?> deleteClass(@PathVariable Long id) {
        try {
            classService.deleteClass(id);
            return ResponseEntity.noContent().build();
        } catch (Exception e) {
            log.error("删除班级失败", e);
            return errorResponse("删除班级失败", e);
        }
    }

    // ClassController.java
    // 通过中间表获取班级学生
    @GetMapping("/{classId}/students/through-stu-class")
    public ResponseEntity<?> getClassStudentsThroughStuClass(@PathVariable Long classId) {
        try {
            List<StudentDetailDTO> students = classService.getStudentsWithDetailsByClassIdThroughStuClass(classId);
            return ResponseEntity.ok(students);
        } catch (Exception e) {
            log.error("通过中间表获取班级学生失败", e);
            return errorResponse("通过中间表获取班级学生失败", e);
        }
    }

    // 通过课程ID获取学生
    @GetMapping("/course/{courseId}/students")
    public ResponseEntity<?> getStudentsByCourseId(@PathVariable Long courseId) {
        try {
            List<StudentDetailDTO> students = classService.getStudentsWithDetailsByCourseId(courseId);
            return ResponseEntity.ok(students);
        } catch (Exception e) {
            log.error("通过课程ID获取学生失败", e);
            return errorResponse("通过课程ID获取学生失败", e);
        }
    }

    // 获取班级学生基本信息
    @GetMapping("/{classId}/students/basic")
    public ResponseEntity<?> getBasicStudentsByClassId(@PathVariable Long classId) {
        try {
            List<StudentBasicDTO> students = classService.getBasicStudentsByClassId(classId);
            return ResponseEntity.ok(students);
        } catch (Exception e) {
            log.error("获取班级学生基本信息失败", e);
            return errorResponse("获取班级学生基本信息失败", e);
        }
    }

    // 获取班级学生及班级信息
    @GetMapping("/{classId}/students/with-class")
    public ResponseEntity<?> getStudentsWithClassByClassId(@PathVariable Long classId) {
        try {
            List<StudentDTO> students = classService.getStudentsWithClassByClassId(classId);
            return ResponseEntity.ok(students);
        } catch (Exception e) {
            log.error("获取班级学生及班级信息失败", e);
            return errorResponse("获取班级学生及班级信息失败", e);
        }
    }


    @GetMapping("/{id}/teachers")
    public ResponseEntity<?> getClassTeachers(@PathVariable Long id) {
        try {
            List<Teacher> teachers = classService.getClassTeachers(id);
            List<TeacherDTO> dtos = teachers.stream()
                    .map(this::convertToTeacherDTO)
                    .collect(Collectors.toList());
            return ResponseEntity.ok(dtos);
        } catch (Exception e) {
            log.error("获取班级教师失败", e);
            return errorResponse("获取班级教师失败", e);
        }
    }

    @GetMapping("/{id}/courses")
    public ResponseEntity<?> getClassCourses(@PathVariable Long id) {
        try {
            List<CouClass> couClasses = classService.getClassCouClasses(id);

            // 转换为DTO，确保处理null值
            List<Map<String, Object>> result = couClasses.stream()
                    .filter(cc -> cc.getCourse() != null) // 过滤掉没有课程的数据
                    .map(cc -> {
                        Map<String, Object> map = new HashMap<>();
                        map.put("couClassId", cc.getId());
                        map.put("status", cc.getStatus());

                        Course course = cc.getCourse();
                        map.put("courseId", course.getId());
                        map.put("courseName", course.getCouName());
                        // 添加其他需要的课程属性

                        return map;
                    })
                    .collect(Collectors.toList());

            return ResponseEntity.ok(result);
        } catch (Exception e) {
            log.error("获取班级课程失败", e);
            return ResponseEntity.internalServerError().body(Map.of(
                    "status", 500,
                    "message", "获取班级课程失败: " + e.getMessage(),
                    "timestamp", System.currentTimeMillis()
            ));
        }
    }

    @GetMapping("/findClaByTea/{teaId}")
    public ResponseEntity<?> findClaByTea(@PathVariable Long teaId) {
        try {
            List<TeaClass> teaClasses = classService.findClaByTea(teaId);
            List<TeaClassDTO> dtos = teaClasses.stream()
                    .map(this::convertToTeaClassDTO)
                    .collect(Collectors.toList());
            return ResponseEntity.ok(dtos);
        } catch (Exception e) {
            log.error("根据教师查找班级失败", e);
            return errorResponse("根据教师查找班级失败", e);
        }
    }

    @GetMapping("/findByTeacher/{page}/{limit}/{name}/{teaId}")
    public ResponseEntity<?> findByTeacher(
            @PathVariable int page,
            @PathVariable int limit,
            @PathVariable String name,
            @PathVariable Long teaId) {
        try {
            Page<TeaClass> teaClasses = classService.findByTeacher(page, limit, name, teaId);
            Page<TeaClassDTO> dtos = teaClasses.map(this::convertToTeaClassDTO);
            return ResponseEntity.ok(dtos);
        } catch (Exception e) {
            log.error("根据教师分页查找班级失败", e);
            return errorResponse("根据教师分页查找班级失败", e);
        }
    }

    @PostMapping("/save")
    public ResponseEntity<?> saveClass(@RequestBody TeaClass teaClass) {
        try {
            TeaClass savedClass = classService.saveClass(teaClass);
            return ResponseEntity.ok(convertToTeaClassDTO(savedClass));
        } catch (Exception e) {
            log.error("保存班级失败", e);
            return errorResponse("保存班级失败", e);
        }
    }

    @DeleteMapping("/delete")
    public ResponseEntity<?> deleteClass(
            @RequestParam Long classId,
            @RequestParam Long courseId) {
        try {
            classService.deleteClass(classId, courseId);
            return ResponseEntity.noContent().build();
        } catch (Exception e) {
            log.error("删除班级关联失败", e);
            return errorResponse("删除班级关联失败", e);
        }
    }

    // DTO转换方法
    private ClassDTO convertToClassDTO(Class cls) {
        if (cls == null) return null;

        ClassDTO dto = new ClassDTO();
        dto.setId(cls.getId());
        dto.setClassName(cls.getClassName());
        dto.setClassStuNum(cls.getClassStuNum());
        dto.setCreateTime(cls.getCreateTime());
        dto.setUpdateTime(cls.getUpdateTime());
        return dto;
    }

    private StudentDTO convertToStudentDTO(Student student) {
        if (student == null) return null;

        StudentDTO dto = new StudentDTO();
        dto.setId(student.getId());
        dto.setStuName(student.getStuName());
        dto.setStuStudyTime(student.getStuStudyTime());
        dto.setStuScore(student.getStuScore());

        if (student.getUser() != null) {
            UserDTO userDTO = new UserDTO();
            userDTO.setId(student.getUser().getId());
            userDTO.setUsername(student.getUser().getUsername());
            userDTO.setRole(student.getUser().getRole());
            dto.setUser(userDTO);
        }
        return dto;
    }

    private TeacherDTO convertToTeacherDTO(Teacher teacher) {
        if (teacher == null) return null;

        TeacherDTO dto = new TeacherDTO();
        dto.setId(teacher.getId());
        dto.setTeaName(teacher.getTeaName());
        dto.setCoursNum(teacher.getCoursNum());
        return dto;
    }

    private CourseDTO convertToCourseDTO(Course course) {
        if (course == null) return null;

        CourseDTO dto = new CourseDTO();
        dto.setId(course.getId());
        dto.setCouName(course.getCouName());
        dto.setCouIntroduction(course.getCouIntroduction());
        dto.setCouPrice(course.getCouPrice());
        return dto;
    }

    private TeaClassDTO convertToTeaClassDTO(TeaClass teaClass) {
        if (teaClass == null) return null;

        TeaClassDTO dto = new TeaClassDTO();
        dto.setId(teaClass.getId());
        dto.setTeaId(teaClass.getTeaId());
        dto.setClassId(teaClass.getClassId());
        return dto;
    }

    private ResponseEntity<Map<String, Object>> errorResponse(String message, Exception e) {
        Map<String, Object> response = new HashMap<>();
        response.put("status", 500);
        response.put("message", message + ": " + e.getMessage());
        response.put("timestamp", System.currentTimeMillis());
        return ResponseEntity.internalServerError().body(response);
    }


    @PostMapping("/{classId}/add-course")
    public ResponseEntity<?> addCourseToClass(
            @PathVariable Long classId,
            @RequestBody Long courseId) {
        try {
            // 检查课程是否已存在
            if (couClassRepository.existsByClassInfoIdAndCourseId(classId, courseId)) {
                return ResponseEntity.badRequest().body(Map.of(
                        "status", 400,
                        "message", "该班级已添加此课程，无需重复添加",
                        "timestamp", System.currentTimeMillis()
                ));
            }

            // 验证班级和课程是否存在
            Class cls = classRepository.findById(classId)
                    .orElseThrow(() -> new IllegalArgumentException("班级不存在"));
            Course course = courseRepository.findById(courseId)
                    .orElseThrow(() -> new IllegalArgumentException("课程不存在"));

            // 创建关联
            CouClass couClass = new CouClass();
            couClass.setClassInfo(cls);
            couClass.setCourse(course);
            couClass.setStatus(1); // 1表示活跃状态
            couClassRepository.save(couClass);

            return ResponseEntity.ok(Map.of(
                    "status", 200,
                    "message", "课程添加成功",
                    "timestamp", System.currentTimeMillis()
            ));
        } catch (IllegalArgumentException e) {
            log.error("参数错误", e);
            return ResponseEntity.badRequest().body(Map.of(
                    "status", 400,
                    "message", e.getMessage(),
                    "timestamp", System.currentTimeMillis()
            ));
        } catch (Exception e) {
            log.error("添加课程到班级失败", e);
            return ResponseEntity.internalServerError().body(Map.of(
                    "status", 500,
                    "message", "添加课程到班级失败: " + e.getMessage(),
                    "timestamp", System.currentTimeMillis()
            ));
        }
    }

    @DeleteMapping("/{classId}/students/{studentId}")
    public ResponseEntity<?> removeStudentFromClass(
            @PathVariable Long classId,
            @PathVariable Long studentId) {
        try {
            // 检查班级是否存在
            if (!classRepository.existsById(classId)) {
                return ResponseEntity.badRequest().body(Map.of(
                        "status", 400,
                        "message", "班级不存在",
                        "timestamp", System.currentTimeMillis()
                ));
            }

            // 检查学生是否存在
            if (!studentRepository.existsById(studentId)) {
                return ResponseEntity.badRequest().body(Map.of(
                        "status", 400,
                        "message", "学生不存在",
                        "timestamp", System.currentTimeMillis()
                ));
            }

            // 删除学生-班级关联
            stuClassRepository.deleteByClassIdAndStudentId(classId, studentId);

            return ResponseEntity.ok(Map.of(
                    "status", 200,
                    "message", "学生删除成功",
                    "timestamp", System.currentTimeMillis()
            ));
        } catch (Exception e) {
            log.error("删除学生失败", e);
            return ResponseEntity.internalServerError().body(Map.of(
                    "status", 500,
                    "message", "删除学生失败: " + e.getMessage(),
                    "timestamp", System.currentTimeMillis()
            ));
        }
    }
}